<!DOCTYPE html>
<html lang="zh">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=0.5 ,user-scalable=no" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<meta http-equiv="X-UA-Compatible" content="ie=edge" />
		<title>2048</title>
		<script src="../javascript/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="../javascript/jquery-3.3.1.js" type="text/javascript" charset="utf-8"></script>
		<script src="../javascript/touch.js" type="text/javascript" charset="utf-8"></script>
		<style type="text/css">
			* {
				padding: 0px;
				margin: 0px;
			}

			#gamebox {
				/*设置整体盒子位置*/
				display: block;
				width: 450px;
				margin-top: 60px;
				margin-left: auto;
				margin-right: auto;
			}

			h1 {
				/*设置主标题大小*/
				font-size: 80px;
				line-height: 80px;
				display: inline-block;
			}

			.best,
			.score {
				float: right;
				display: inline-block;
				height: 80px;
				text-align: center;
				background-color: #23527C;
				margin-left: 15px;
				padding: 0 15px 0 15px;
				border-radius: 12px;
				width: 80px;
				font-size: 18px;
				line-height: 30px;
			}

			.numbers {
				font-size: 30px;
				line-height: 50px;
				color: #C4FFFF;
			}

			.row {
				/*加行隔开效果*/
				margin-top: 15px;
			}

			.words {
				/*字体大小和间距*/
				height: 30px;
				line-height: 15px;
				font-size: 15px;
				display: inline-block;
			}

			.restart {
				/*重启按钮的设置*/
				float: right;
				height: 30px;
				width: 100px;
				border-radius: 5px;
				background-color: #C4E3F3;
				border: none;
			}

			.restart:hover {
				background-color: #C4E3d3
			}

			.restart:active {
				background-color: #C4ffff
			}

			.game {
				margin-top: 15px;
				width: 450px;
				height: 450px;
				background-color: #bbada0;
				border-radius: 15px;
				line-height: 0;
			}

			.gameBlock {
				background-color: #eee4da;
				display: inline-block;
				height: 100px;
				width: 100px;
				margin-top: 10px;
				margin-left: 10px;
				border-radius: 8px;
				float: left;
				line-height: 100px;
				text-align: center;
				font-size: 40px;
			}

			.litterBox {
				display: inline-block;
				height: 100px;
				width: 100px;
				border-radius: 8px;
				position: relative;
			}
		</style>
	</head>

	<body>
		<div id="gamebox">
			<header>
				<div id="score">
					<h1>2048</h1>
					<div class="best">
						<span>BEST</span><br />
						<span class="numbers">{{best}}</span>
					</div>
					<div class="score">
						<span>SCORE</span><br />
						<span class="numbers">{{score}}</span>
					</div>
				</div>
				<div class="row">
					<div class="words">
						<strong>Play 2048 Game Online</strong>
						<p>Join the numbers and get to the <strong>2048 tile</strong>!</p>
					</div>
					<button class='restart' v-on:click="restart">New Game</button>
				</div>
			</header>
			<div class="game" id='game'>
				<div class="gameBlock" v-for="i in blocks"><span class="litterBox" v-bind:style="{backgroundColor:i.value==0?'transparent':'#' + (15589576 - i.value - i.value * 100 * 4).toString(16)}">{{i.value==0?"":i.value}}</span></div>
			</div>
		</div>

	</body>
	<script type="text/javascript">
		function move(dir,e){//触屏控制
			game2048.move(dir);
		}
	</script>
	<script type="text/javascript">
		function reSet() { //用于测试,移除浏览器储存数据
			localStorage.removeItem("2048score");
			localStorage.removeItem("2048best");
		}

		function Data() { //设置vue对象中的数据
			for (var i = 0; i < 16; i++) {
				this['block_' + i] = 0;
			}
			this['numbers'] = 0;
			this['best'] = 0;
			this['score'] = 0;
		}

		function sleep(time) { //睡眠
			var t = Date.now();
			while (Date.now() - t < time) {;
			}
		}
	
		window.onload = function() {
			//setHtml();
			game2048 = new Vue({
				el: "#gamebox",
				data: {
					numbers: 0,
					best: 0,
					score: 0,
					blocks: function() {
						var blocks = new Array();
						for (var i = 0; i < 16; i++) {
							blocks.push({
								value: 0
							});
						}
						return blocks;
					}()
				},
				methods: {
					setNum: function() { //随机设置一个数字
						var place = Math.round(Math.random() * 100) % (16 - this.numbers) + 1;
						for (var i = 0; i < 16; i++) {
							if (this.blocks[i].value == 0) {
								place--;
							}
							if (place == 0) {
								var num = Math.random() > 0.5 ? 2 : 4;
								this.blocks[i].value = num;
								this.numbers++;
								return;
							}
						}
					},
					restart: function() { //重置按钮
						this.numbers = 0;
						for (var i = 0; i < 16; i++) {
							this.$data.blocks[i].value = 0;
						}
						this.$data.score = 0;
						this.setNum();
						this.setNum();
						this.save();
					},
					move: function(dir) { //向做移动
						var flag = 0;
						for (var i = 0; i < 4; i++) {
							for (var k = 0; k < 4; k++) {
								var n;
								switch (dir) {
									case 'left':
										n = i * 4 + k;
										break;
									case 'right':
										n = i * 4 + 3 - k;
										break;
									case 'up':
										n = i + k * 4;;
										break;
									case 'down':
										n = (3 - k) * 4 + 3 - i;
										break;
								}
								if (this.blocks[n].value == 0) {
									for (var a = k + 1; a < 4; a++) {
										var m;
										switch (dir) {
											case 'left':
												m = i * 4 + a;
												break;
											case 'right':
												m = i * 4 + 3 - a;
												break;
											case 'up':
												m = i + a * 4;
												break;
											case 'down':
												m = (3 - a) * 4 + 3 - i;
												break;
										}
										if (m > 15) {
											break;
										}
										if (this.blocks[m].value != 0) { //如果为空就把右边非空值移动过来
											num = this.blocks[m].value;
											this.blocks[n].value = num;
											this.blocks[m].value = 0;
											flag = 1;
											break;
										}
									}
								}
								if (this.$data['block_' + n] != 0) { //如果不为空,判断是否有相同值
									for (var a = k + 1; a < 4; a++) {
										var m;
										switch (dir) {
											case 'left':
												m = i * 4 + a;
												break;
											case 'right':
												m = i * 4 + 3 - a;
												break;
											case 'up':
												m = i + a * 4;
												break;
											case 'down':
												m = (3 - a) * 4 + 3 - i;
												break;
										}
										if (m > 15) {
											break;
										}
										if (this.blocks[m].value != 0) {
											if (this.blocks[n].value == this.blocks[m].value) {
												num = this.blocks[n].value * 2;
												this.blocks[n].value = num;
												this.blocks[m].value = 0;
												this.$data.score += this.blocks[n].value; //vue 部分
												if (this.$data.score > this.$data.best) {
													this.$data.best = this.$data.score;
												}
												this.numbers--;
												flag = 1;
											}
											break;
										}
									}
								}
							}
						}
						if (flag == 1) {
							this.setNum();
						}
					},
					
					keydown: function(e) {
						switch (e.key) {
							case 'ArrowLeft':
								this.move('left');
								break;
							case 'ArrowUp':
								this.move('up');
								break;
							case 'ArrowDown':
								this.move('down');
								break;
							case 'ArrowRight':
								this.move('right');
								break;
							case 'a':
								this.move('left');
								break;
							case 'w':
								this.move('up');
								break;
							case 's':
								this.move('down');
								break;
							case 'd':
								this.move('right');
								break;
							case 'A':
								this.move('left');
								break;
							case 'W':
								this.move('up');
								break;
							case 'S':
								this.move('down');
								break;
							case 'D':
								this.move('right');
								break;
						}
					},
					keyup: function() {
						if (this.isGameOver()) {
							alert('Game Over!');
							this.restart()
						}
						this.save();
					},
					isGameOver: function() { //判断是否游戏结束
						if (this.numbers != 16) {
							return false;
						} else {
							for (var i = 0; i < 4; i++) {
								for (var k = 0; k < 4; k++) {
									if (k != 3 && this.blocks[i * 4 + k].value == this.blocks[i * 4 + k + 1].value) {
										return false;
									}
									if (i != 3 && this.blocks[i * 4 + k].value == this.blocks[i * 4 + k + 4].value) {
										return false;
									}
								}

							}
							return true;
						}
					},
					save: function() {
						if (typeof localStorage != undefined) {
							for (var key in this.$data) {
								if (key == 'blocks') {
									for (var i in this.blocks) {
										localStorage.setItem('2048' + i, this.blocks[i].value);
									}
								} else {
									localStorage.setItem("2048" + key, this.$data[key]);
								}
							}
						}
					},
					load: function() {
						if (typeof localStorage != undefined) {
							for (var key in this.$data) {
								if (key != 'blocks') {
									this.$data[key] = new Number(localStorage.getItem("2048" + key));
								} else {
									for (var i in this.blocks) {
										this.blocks[i].value = localStorage.getItem('2048' + i);
									}
								}

							}
							if (this.$data.score == 0 || this.$data.score == undefined) {
								return 0;
							}
							return 1;
						} else {
							return 0;
						}
					}
				}
			});
			if (!game2048.load()) {
				game2048.restart();
			}
			window.ontouchstart=touch_control(document.getElementById('game'),move);
			window.onkeydown = game2048.keydown;
			window.onkeyup = game2048.keyup;
		};
	</script>
</html>
